﻿@using Aspire.Dashboard.Components.Controls.Grid
@using Aspire.Dashboard.Model
@using Aspire.Dashboard.Model.Otlp
@using Aspire.Dashboard.Otlp.Model
@using Aspire.Dashboard.Resources
@using Aspire.Dashboard.Utils
@inject IStringLocalizer<ControlsStrings> Loc
@inject IStringLocalizer<Dialogs> DialogsLoc

<div class="span-details-layout">
    <FluentToolbar Orientation="Orientation.Horizontal">
        <div>
            @((MarkupString)string.Format(ControlsStrings.SpanDetailsResource, ViewModel.Span.Source.Resource.ResourceName))
        </div>
        <FluentDivider Role="DividerRole.Presentation" Orientation="Orientation.Vertical" />
        <div>
            @((MarkupString)string.Format(ControlsStrings.SpanDetailsDuration, DurationFormatter.FormatDuration(ViewModel.Span.Duration)))
        </div>
        <FluentDivider Role="DividerRole.Presentation" Orientation="Orientation.Vertical" />
        <div>
            @{
                // Start time for root span is zero. We don't want to display the smallest unit (0μs) because that looks odd. Use the unit from duration.
                var startTime = ViewModel.Span.StartTime - ViewModel.Span.Trace.FirstSpan.StartTime;
                var formattedStartTime = startTime > TimeSpan.Zero ? DurationFormatter.FormatDuration(startTime) : $"0{DurationFormatter.GetUnit(ViewModel.Span.Duration)}";
            }
            @((MarkupString)string.Format(ControlsStrings.SpanDetailsStartTime, formattedStartTime))
        </div>
        <FluentAnchor slot="end" Appearance="Appearance.Lightweight" Href="@DashboardUrls.StructuredLogsUrl(spanId: ViewModel.Span.SpanId)">@Loc[nameof(ControlsStrings.ViewLogsLink)]</FluentAnchor>
        <FluentDivider slot="end" Role="DividerRole.Presentation" Orientation="Orientation.Vertical" />
        <FluentSearch Placeholder="@Loc[nameof(ControlsStrings.FilterPlaceholder)]"
                      Immediate="true"
                      Autofocus="true"
                      @bind-Value="_filter"
                      slot="end" />
    </FluentToolbar>
    <div class="property-grid-container">
        <FluentAccordion>
            <FluentAccordionItem Heading="@Loc[nameof(ControlsStrings.SpanDetailsSpanHeader)]" Expanded="true">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredItems.Count()
                    </FluentBadge>
                </div>
                <PropertyGrid TItem="TelemetryPropertyViewModel"
                              Items="@FilteredItems"
                              GridTemplateColumns="1fr 2fr"
                              HighlightText="@_filter"
                              ValueComponents="_valueComponents" />
            </FluentAccordionItem>
            <FluentAccordionItem Heading="@Loc[nameof(ControlsStrings.SpanDetailsContextHeader)]" Expanded="true">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredContextItems.Count()
                    </FluentBadge>
                </div>
                <PropertyGrid TItem="TelemetryPropertyViewModel"
                              Items="@FilteredContextItems"
                              GridTemplateColumns="1fr 2fr"
                              HighlightText="@_filter"
                              ValueComponents="@_valueComponents" />
            </FluentAccordionItem>
            <FluentAccordionItem Heading="@Loc[nameof(ControlsStrings.SpanDetailsResourceHeader)]" Expanded="true">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredResourceItems.Count()
                    </FluentBadge>
                </div>
                <PropertyGrid TItem="TelemetryPropertyViewModel"
                              Items="@FilteredResourceItems"
                              GridTemplateColumns="1fr 2fr"
                              HighlightText="@_filter"
                              ValueComponents="@_valueComponents" />
            </FluentAccordionItem>
            <FluentAccordionItem Heading="@Loc[nameof(ControlsStrings.SpanDetailsEventsHeader)]" Expanded="@_isSpanEventsExpanded">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredSpanEvents.Count()
                    </FluentBadge>
                </div>
                <PropertyGrid TItem="OtlpSpanEvent"
                              Items="@FilteredSpanEvents"
                              GridTemplateColumns="1fr 2fr"
                              NameColumnTitle="@(Loc[nameof(ControlsStrings.TimeOffsetColumnHeader)])"
                              ValueColumnTitle="@(Loc[nameof(ControlsStrings.EventColumnHeader)])"
                              IsNameSortable="false"
                              IsValueSortable="false"
                              HighlightText="@_filter"
                              Multiline="true">
                    <ExtraValueContent>
                        @if (context.Attributes.Length > 0)
                        {
                            <PropertyGrid TItem="OtlpSpanAttributeItem"
                                          Items="@context.Attributes.Select(pair => new OtlpSpanAttributeItem(pair.Key, pair.Value)).AsQueryable()"
                                          GridTemplateColumns="1fr 2fr"
                                          IsNameSortable="false"
                                          IsValueSortable="false"
                                          GenerateHeader="GenerateHeaderOption.Default" />
                        }
                    </ExtraValueContent>
                </PropertyGrid>
            </FluentAccordionItem>
            <FluentAccordionItem Heading="@Loc[nameof(ControlsStrings.SpanDetailsLinksHeader)]" Expanded="@_isSpanLinksExpanded">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredSpanLinks.Count()
                    </FluentBadge>
                </div>
                <FluentDataGrid ColumnResizeLabels="@_resizeLabels"
                                ColumnSortLabels="@_sortLabels"
                                HeaderCellAsButtonWithMenu="true"
                                ResizeType="DataGridResizeType.Discrete"
                                ResizableColumns="true"
                                TGridItem="SpanLinkViewModel"
                                Items="@FilteredSpanLinks"
                                Style="width:100%"
                                RowSize="DataGridRowSize.Medium"
                                GridTemplateColumns="4fr 1fr"
                                ShowHover="true"
                                Multiline="true">
                    <TemplateColumn Title="@Loc[nameof(ControlsStrings.SpanDetailsSpanColumnHeader)]">
                        @WriteSpanLink(context)
                    </TemplateColumn>
                    <TemplateColumn Title="@Loc[nameof(ControlsStrings.SpanDetailsDetailsColumnHeader)]">
                        <FluentButton OnClick="@(() => OnViewDetailsAsync(context))" Appearance="Appearance.Lightweight" Class="button-hyperlink" IconStart="new Icons.Regular.Size16.GanttChart()">
                            @OtlpHelpers.ToShortenedId(context.SpanId)
                        </FluentButton>
                    </TemplateColumn>
                </FluentDataGrid>
            </FluentAccordionItem>
            <FluentAccordionItem Heading="@Loc[nameof(ControlsStrings.SpanDetailsBacklinksHeader)]" Expanded="@_isSpanBacklinksExpanded">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredSpanBacklinks.Count()
                    </FluentBadge>
                </div>
                <FluentDataGrid ColumnResizeLabels="@_resizeLabels"
                                ColumnSortLabels="@_sortLabels"
                                HeaderCellAsButtonWithMenu="true"
                                ResizeType="DataGridResizeType.Discrete"
                                ResizableColumns="true"
                                TGridItem="SpanLinkViewModel"
                                Items="@FilteredSpanBacklinks"
                                Style="width:100%"
                                RowSize="DataGridRowSize.Medium"
                                GridTemplateColumns="4fr 1fr"
                                ShowHover="true"
                                Multiline="true">
                    <TemplateColumn Title="@Loc[nameof(ControlsStrings.SpanDetailsSpanColumnHeader)]">
                        @WriteSpanLink(context)
                    </TemplateColumn>
                    <TemplateColumn Title="@Loc[nameof(ControlsStrings.SpanDetailsDetailsColumnHeader)]">
                        <FluentButton OnClick="@(() => OnViewDetailsAsync(context))" Appearance="Appearance.Lightweight" Class="button-hyperlink" IconStart="new Icons.Regular.Size16.GanttChart()">
                            @OtlpHelpers.ToShortenedId(context.SpanId)
                        </FluentButton>
                    </TemplateColumn>
                </FluentDataGrid>
            </FluentAccordionItem>
        </FluentAccordion>
    </div>
</div>

@code {
    RenderFragment WriteSpanLink(SpanLinkViewModel context)
    {
        var content = context.Span != null
            ? SpanWaterfallViewModel.GetTitle(context.Span, ViewModel.Resources)
            : $"{Loc[nameof(ControlsStrings.SpanDetailsSpanPrefix)]}: {OtlpHelpers.ToShortenedId(context.SpanId)}";
        var color = context.Span != null
            ? ColorGenerator.Instance.GetColorHexByKey(OtlpResource.GetResourceName(context.Span.Source, ViewModel.Resources))
            : "transparent";

        return @<div>
        <div class="spanlink-container" style="height:32px;">
            <span class="spanlink-text" title="@content" style="padding-left:5px; border-left-width: 5px; border-left-style: solid; border-left-color: @(color);">
                @content
            </span>
        </div>
        @if (context.Attributes.Length > 0)
        {
            <PropertyGrid TItem="OtlpSpanAttributeItem"
                          Items="@context.Attributes.Select(pair => new OtlpSpanAttributeItem(pair.Key, pair.Value)).AsQueryable()"
                          GridTemplateColumns="1fr 2fr"
                          IsNameSortable="false"
                          IsValueSortable="false"
                          GenerateHeader="GenerateHeaderOption.Default" />
        }
    </div>;
    }
}
